package com.snow.common.component;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import com.snow.component.IStorageComponent;
import com.snow.exception.CommonRuntimeException;
import com.snow.model.ILoginUser;
import com.snow.common.entity.SystemAnnexEntity;
import com.snow.common.repository.SystemAnnexRepository;
import com.snow.service.IAuthComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class SystemAnnexComponent {
    final SystemAnnexRepository systemAnnexRepository;
    final IAuthComponent authComponent;
    final IStorageComponent storageComponent;
    private final StringRedisTemplate stringRedisTemplate;


    public SystemAnnexComponent(SystemAnnexRepository systemAnnexRepository, @Autowired(required = false) IAuthComponent authComponent, IStorageComponent storageComponent, StringRedisTemplate stringRedisTemplate) {
        this.systemAnnexRepository = systemAnnexRepository;
        this.authComponent = authComponent;
        this.storageComponent = storageComponent;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public SystemAnnexEntity publicSave(Integer recordId, String type, InputStream fileInputStream, String fileName) {
        return save(recordId, type, fileInputStream, fileName, true);
    }
    public SystemAnnexEntity save(Integer recordId, String type, InputStream fileInputStream, String fileName) {

        return save(recordId, type, fileInputStream, fileName, false);
    }
    private SystemAnnexEntity save(Integer recordId, String type, InputStream fileInputStream, String fileName, boolean isPublic) {
        SystemAnnexEntity annexEntity = new SystemAnnexEntity();
        ILoginUser currentUser = authComponent.getCurrentUser();
        annexEntity.setCreateInfo(currentUser);
        annexEntity.setTenantId(authComponent.getCurrentUser().getTenantId());
        annexEntity.setRecordId(recordId);
        annexEntity.setType(type);
        String savePath = storageComponent.save(fileInputStream, fileName, isPublic);
        annexEntity.setSavePath(savePath);
        annexEntity.setSaveType(0);
        systemAnnexRepository.save(annexEntity);
        annexEntity.setPreviewPath(storageComponent.getPreviewUrl(annexEntity.getSavePath()));
        return annexEntity;
    }

    public String cashFile(MultipartFile file) {
        String cashId = IdUtil.fastSimpleUUID();
        try {
            stringRedisTemplate.opsForValue().set(cashId, file.getOriginalFilename() + ":" + Base64.encode(file.getInputStream()), 2, TimeUnit.HOURS);
        } catch (IOException e) {
            throw new CommonRuntimeException("系统内部错误，请联系管理员");
        }
        return cashId;
    }

    public SystemAnnexEntity saveCashFile(Integer recordId, String type, String cashFileId) {
        String cashFileStr = stringRedisTemplate.opsForValue().get(cashFileId);
        String[] cashFile = cashFileStr.split(":");
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        Base64.decodeToStream(cashFile[1], outputStream, true);
        return save(recordId, type, IoUtil.toStream(outputStream), cashFile[0]);
    }

    public String getPreviewUrl(Integer recordId, String type) {
        SystemAnnexEntity annexEntity = systemAnnexRepository.lambdaQuery().equal("recordId", recordId).equal("type", type).one();
        return annexEntity.getPreviewPath();
    }


    public String getPreviewUrl(String path) {
        return storageComponent.getPreviewUrl(path);
    }

    public List<SystemAnnexEntity> list(String type, Integer recordId) {
        List<SystemAnnexEntity> list = systemAnnexRepository.lambdaQuery()
                .equal("type", type)
                .equal("recordId", recordId).findAll();
        for (SystemAnnexEntity annexEntity : list) {
            annexEntity.setPreviewPath(storageComponent.getPreviewUrl(annexEntity.getSavePath()));
        }
        return list;
    }
}
